/**
  ******************************************************************************
  * @file    usbd_cdc_core.c
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    22-July-2011
  * @brief   This file provides the high layer firmware functions to manage the 
  *          following functionalities of the USB CDC Class:
  *           - Initialization and Configuration of high and low layer
  *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
  *           - OUT/IN data transfer
  *           - Command IN transfer (class requests management)
  *           - Error management
  *           
  *  @verbatim
  *      
  *          ===================================================================      
  *                                CDC Cflass Driver Description
  *          =================================================================== 
  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus 
  *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
  *           This driver implements the following aspects of the specification:
  *             - Device descriptor management
  *             - Configuration descriptor management
  *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
  *             - Requests management (as described in section 6.2 in specification)
  *             - Abstract Control Model compliant
  *             - Union Functional collection (using 1 IN endpoint for control)
  *             - Data interface class

  *           @note
  *             For the Abstract Control Model, this core allows only transmitting the requests to
  *             lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
  *             perform relative actions.
  * 
  *           These aspects may be enriched or modified for a specific user application.
  *          
  *            This driver doesn't implement the following aspects of the specification 
  *            (but it is possible to manage these features with some modifications on this driver):
  *             - Any class-specific aspect relative to communication classes should be managed by user application.
  *             - All communication classes other than PSTN are not managed
  *      
  *  @endverbatim
  *                                  
  ******************************************************************************               
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_core.h"
#include "usbd_desc.h"
#include "usbd_req.h"
#include "main.h"
#include "debug.h"
#include "../../../../../DDIC/AllDDIC.h"

u16 crc16_data1 = 0;
//-----------------------------------Version Set--------------------------------------------
#define FW_Version      0x01
#define FW_SubVersion   0x09
//------------------------------------------------------------------------------------------
u8 DUAL_SPI_MODE = 0;
u8 NUM=0;
u8 Valid_BMP_No = 0,PicShowedNum=0;
OLED_Para OLED;
u32 WriteAddress = Inter_Flash_Addr;
u32 buffer1[BMP_R_Byte_Max-1];
u8	Uart_rx_flag = REC_W_LCDCONF_FLAG;
u8  buffer[BMP_R_Byte_Max];
u32 i = 0,j = 0,k = 0;
u32 File_length=0;
u8 SendTo_PC_cfgFile=0;
u32 VCP_Receive_True_num=0;

u32 USB_Rx_Demura_Total_Num=0;
u32 USB_Tx_Demura_Num=0;
u32 USB_Rx_Demura_Total_Num_Temp=0;
u32 USB_Rx_Demura_Num=0;
u32 USB_Rx_Demura=0;
u8 DemuraIctype=0;
u8 DemuraSize_H8=0;
u8 DemuraSize_L8=0;
//u32 USB_Demura_Transmode_start=0;
u8 USB_Rx_Demura_End_Flag=0;
u32 USB_Rx_2C3C=0;

u32 ICS307_Valid_Data=0;
u32 ICS307_Buf_Data=0;
u32 ICS307_Buf_Data1 = 0;
u8 PatternR=0,PatternG=0,PatternB=0;
u8 Pure_Color_Flag = 0;
u8 CS_Master = CS1;
u8 CS_Slaver = CS2;
u16 OLED_X0,OLED_X1,OLED_Y0,OLED_Y1,OLED_X_VALUE,OLED_Y_VALUE;
u16 LP_B7_Data,HS_B7_Data;
u8  Rec_first_line_Flag = 1;
u8 RM35x_otptime = 0;
u32 SSD28xx_Code[SSD2828_Code_Max];                         //存放 SSD2828配置 数据
u32 Timing_and_InitCode[IniCode_Max];                       //更新时 临时存放Timing和Driver IC初始化代码
u8  SSD28xxCode_count = 0;                                  //SSD2828配置代码的 行数
u8  InitCode_valid[IniCode_table_num][IniCode_Max];         //存放 Driver IC初始化代码
u8  Buffer_ReadCode[255];
u16 InitCode_count=0;                                     //DriverIC初始化代码的 行数
u32 Code_length = 0;
u8  Receive_Code_flag = 0;
u8 	Demura_send_flag=0;
u8  Demura_OLEDModule_flag=0;
u8  Receive_BIN_Flag = 0;
u8  Receive_BIN_Flag1 = 0;
u8  Receive_BIN_Flag2 = 0;
u32 Receive_BIN_Length = 0;
u32 bw;
u32 USB_DemuraParament_Num = 0;      //TC1105  receive parameter data num
u32  Device_ID_Buf[2];
u32  Device_ID = 2;
u32  Device_Addr = 0;
//----------------------------------------------------------------------------------
u8 gamma_read_num=0;
u8 gamma_write_num=0;

/** @defgroup usbd_cdc_Private_Macros
  * @{
  */ 
/**
  * @}
  */ 
__IO  uint8_t USB_StatusDataSended = 1;
__IO  uint32_t USB_ReceivedCount = 0;
/** @defgroup usbd_cdc_Private_FunctionPrototypes
  * @{
  */

/*********************************************
   CDC Device library callbacks
 *********************************************/
static uint8_t  usbd_cdc_Init        (void  *pdev, uint8_t cfgidx);
static uint8_t  usbd_cdc_DeInit      (void  *pdev, uint8_t cfgidx);
static uint8_t  usbd_cdc_Setup       (void  *pdev, USB_SETUP_REQ *req);
static uint8_t  usbd_cdc_EP0_RxReady  (void *pdev);
static uint8_t  usbd_cdc_DataIn      (void *pdev, uint8_t epnum);
static uint8_t  usbd_cdc_DataOut     (void *pdev, uint8_t epnum);
static uint8_t  usbd_cdc_SOF         (void *pdev);

/*********************************************
   CDC specific management functions
 *********************************************/
static void Handle_USBAsynchXfer  (void *pdev);
static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
#ifdef USE_USB_OTG_HS  
static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
#endif
/**
  * @}
  */ 

/** @defgroup usbd_cdc_Private_Variables
  * @{
  */ 
extern CDC_IF_Prop_TypeDef  APP_FOPS;
extern uint8_t USBD_DeviceDesc   [USB_SIZ_DEVICE_DESC];
extern void DemuraParamentWrite(USB_OTG_CORE_HANDLE *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8 buffer[],u16 LP_B7_Data,u16 HS_B7_Data);
extern void Demura_purui(USB_OTG_CORE_HANDLE *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8 buffer[],u16 LP_B7_Data,u16 HS_B7_Data);
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN static __IO uint32_t  usbd_cdc_AltSet  __ALIGN_END = 0;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t USB_Rx_Buffer   [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t APP_Rx_Buffer   [APP_RX_DATA_SIZE] __ALIGN_END ;  //其实是一个循环缓冲区


#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;

uint32_t APP_Rx_ptr_in  = 0;    //APP_Rx_Buffer指明了其数据进来的位置,当USART 接收到数据时，将数据存储于 APP_Rx_ptr_in 指定的位置
uint32_t APP_Rx_ptr_out = 0;    //APP_Rx_Buffer指明其数据取出 的位置，当 USB 到 FIFO 中取出数据时，起始地址由 APP_Rx_ptr_out 决定
uint32_t APP_Rx_length  = 0;

uint8_t  USB_Tx_State = 0;

static uint32_t cdcCmd = 0xFF;
static uint32_t cdcLen = 0;

/* CDC interface class callbacks structure */
USBD_Class_cb_TypeDef  USBD_CDC_cb = 
{
  usbd_cdc_Init,
  usbd_cdc_DeInit,
  usbd_cdc_Setup,
  NULL,                 /* EP0_TxSent, */
  usbd_cdc_EP0_RxReady,
  usbd_cdc_DataIn,
  usbd_cdc_DataOut,
  usbd_cdc_SOF,
  NULL,
  NULL,     
  USBD_cdc_GetCfgDesc,
#ifdef USE_USB_OTG_HS   
  USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
#endif /* USE_USB_OTG_HS  */
};

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{
  /*Configuration Descriptor*/
  0x09,   /* bLength: Configuration Descriptor size */
  USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  0x00,
  0x02,   /* bNumInterfaces: 2 interface */
  0x01,   /* bConfigurationValue: Configuration value */
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
  0xC0,   /* bmAttributes: self powered */
  0x32,   /* MaxPower 0 mA */
  
  /*---------------------------------------------------------------------------*/
  
  /*Interface Descriptor */
  0x09,   /* bLength: Interface Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
  /* Interface descriptor type */
  0x00,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x01,   /* bNumEndpoints: One endpoints used */
  0x02,   /* bInterfaceClass: Communication Interface Class */
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
  0x01,   /* bInterfaceProtocol: Common AT commands */
  0x00,   /* iInterface: */
  
  /*Header Functional Descriptor*/
  0x05,   /* bLength: Endpoint Descriptor size */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x00,   /* bDescriptorSubtype: Header Func Desc */
  0x10,   /* bcdCDC: spec release number */
  0x01,
  
  /*Call Management Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  0x00,   /* bmCapabilities: D0+D1 */
  0x01,   /* bDataInterface: 1 */
  
  /*ACM Functional Descriptor*/
  0x04,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  0x02,   /* bmCapabilities */
  
  /*Union Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x06,   /* bDescriptorSubtype: Union func desc */
  0x00,   /* bMasterInterface: Communication class interface */
  0x01,   /* bSlaveInterface0: Data Class Interface */
  
  /*Endpoint 2 Descriptor*/
  0x07,                           /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
  CDC_CMD_EP,                     /* bEndpointAddress */
  0x03,                           /* bmAttributes: Interrupt */
  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
  HIBYTE(CDC_CMD_PACKET_SZE),
#ifdef USE_USB_OTG_HS
  0x10,                           /* bInterval: */
#else
  0xFF,                           /* bInterval: */
#endif /* USE_USB_OTG_HS */
  
  /*---------------------------------------------------------------------------*/
  
  /*Data class interface descriptor*/
  0x09,   /* bLength: Endpoint Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
  0x01,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x02,   /* bNumEndpoints: Two endpoints used */
  0x0A,   /* bInterfaceClass: CDC */
  0x00,   /* bInterfaceSubClass: */
  0x00,   /* bInterfaceProtocol: */
  0x00,   /* iInterface: */
  
  /*Endpoint OUT Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_OUT_EP,                        /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
  0x00,                              /* bInterval: ignore for Bulk transfer */
  
  /*Endpoint IN Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_IN_EP,                         /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
  0x00                               /* bInterval: ignore for Bulk transfer */
} ;

#ifdef USE_USB_OTG_HS
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
    #pragma data_alignment=4   
  #endif
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ 
__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{ 
  0x09,   /* bLength: Configuation Descriptor size */
  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
  USB_CDC_CONFIG_DESC_SIZ,
  0x00,
  0x02,   /* bNumInterfaces: 2 interfaces */
  0x01,   /* bConfigurationValue: */
  0x04,   /* iConfiguration: */
  0xC0,   /* bmAttributes: */
  0x32,   /* MaxPower 100 mA */  
  
  /*Interface Descriptor */
  0x09,   /* bLength: Interface Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
  /* Interface descriptor type */
  0x00,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x01,   /* bNumEndpoints: One endpoints used */
  0x02,   /* bInterfaceClass: Communication Interface Class */
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
  0x01,   /* bInterfaceProtocol: Common AT commands */
  0x00,   /* iInterface: */
  
  /*Header Functional Descriptor*/
  0x05,   /* bLength: Endpoint Descriptor size */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x00,   /* bDescriptorSubtype: Header Func Desc */
  0x10,   /* bcdCDC: spec release number */
  0x01,
  
  /*Call Management Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  0x00,   /* bmCapabilities: D0+D1 */
  0x01,   /* bDataInterface: 1 */
  
  /*ACM Functional Descriptor*/
  0x04,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  0x02,   /* bmCapabilities */
  
  /*Union Functional Descriptor*/
  0x05,   /* bFunctionLength */
  0x24,   /* bDescriptorType: CS_INTERFACE */
  0x06,   /* bDescriptorSubtype: Union func desc */
  0x00,   /* bMasterInterface: Communication class interface */
  0x01,   /* bSlaveInterface0: Data Class Interface */
  
  /*Endpoint 2 Descriptor*/
  0x07,                           /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
  CDC_CMD_EP,                     /* bEndpointAddress */
  0x03,                           /* bmAttributes: Interrupt */
  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
  HIBYTE(CDC_CMD_PACKET_SZE),
  0xFF,                           /* bInterval: */
  
  /*---------------------------------------------------------------------------*/
  
  /*Data class interface descriptor*/
  0x09,   /* bLength: Endpoint Descriptor size */
  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
  0x01,   /* bInterfaceNumber: Number of Interface */
  0x00,   /* bAlternateSetting: Alternate setting */
  0x02,   /* bNumEndpoints: Two endpoints used */
  0x0A,   /* bInterfaceClass: CDC */
  0x00,   /* bInterfaceSubClass: */
  0x00,   /* bInterfaceProtocol: */
  0x00,   /* iInterface: */
  
  /*Endpoint OUT Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
  CDC_OUT_EP,                        /* bEndpointAddress */
  0x02,                              /* bmAttributes: Bulk */
  0x40,                              /* wMaxPacketSize: */
  0x00,
  0x00,                              /* bInterval: ignore for Bulk transfer */
  
  /*Endpoint IN Descriptor*/
  0x07,   /* bLength: Endpoint Descriptor size */
  USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
  CDC_IN_EP,                        /* bEndpointAddress */
  0x02,                             /* bmAttributes: Bulk */
  0x40,                             /* wMaxPacketSize: */
  0x00,
  0x00                              /* bInterval */
};
#endif /* USE_USB_OTG_HS  */




/**
  * @}
  */ 

/** @defgroup usbd_cdc_Private_Functions
  * @{
  */ 

/**
  * @brief  usbd_cdc_Init
  *         Initilaize the CDC interface
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  usbd_cdc_Init (void  *pdev, 
                               uint8_t cfgidx)
{
  uint8_t *pbuf;

  /* Open EP IN */
  DCD_EP_Open(pdev,
              CDC_IN_EP,
              CDC_DATA_IN_PACKET_SIZE,
              USB_OTG_EP_BULK);
  
  /* Open EP OUT */
  DCD_EP_Open(pdev,
              CDC_OUT_EP,
              CDC_DATA_OUT_PACKET_SIZE,
              USB_OTG_EP_BULK);
  
  /* Open Command IN EP */
  DCD_EP_Open(pdev,
              CDC_CMD_EP,
              CDC_CMD_PACKET_SZE,
              USB_OTG_EP_INT);
  
  pbuf = (uint8_t *)USBD_DeviceDesc;
  pbuf[4] = DEVICE_CLASS_CDC;
  pbuf[5] = DEVICE_SUBCLASS_CDC;
  
  /* Initialize the Interface physical components */
  APP_FOPS.pIf_Init();

  /* Prepare Out endpoint to receive next packet */
  DCD_EP_PrepareRx(pdev,
                   CDC_OUT_EP,
                   (uint8_t*)(USB_Rx_Buffer),
                   CDC_DATA_OUT_PACKET_SIZE);
  
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_Init
  *         DeInitialize the CDC layer
  * @param  pdev: device instance
  * @param  cfgidx: Configuration index
  * @retval status
  */
static uint8_t  usbd_cdc_DeInit (void  *pdev, 
                                 uint8_t cfgidx)
{
  /* Open EP IN */
  DCD_EP_Close(pdev,
              CDC_IN_EP);
  
  /* Open EP OUT */
  DCD_EP_Close(pdev,
              CDC_OUT_EP);
  
  /* Open Command IN EP */
  DCD_EP_Close(pdev,
              CDC_CMD_EP);

  /* Restore default state of the Interface physical components */
  APP_FOPS.pIf_DeInit();
  
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_Setup
  *         Handle the CDC specific requests
  * @param  pdev: instance
  * @param  req: usb requests
  * @retval status
  */
static uint8_t  usbd_cdc_Setup (void  *pdev, 
                                USB_SETUP_REQ *req)
{
  uint16_t len;
  uint8_t  *pbuf;
  
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {
    /* CDC Class Requests -------------------------------*/
  case USB_REQ_TYPE_CLASS :
      /* Check if the request is a data setup packet */
      if (req->wLength)
      {
        /* Check if the request is Device-to-Host */
        if (req->bmRequest & 0x80)
        {
          /* Get the data to be sent to Host from interface layer */
          APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
          
          /* Send the data to the host */
          USBD_CtlSendData (pdev, 
                            CmdBuff,
                            req->wLength);          
        }
        else /* Host-to-Device requeset */
        {
          /* Set the value of the current command to be processed */
          cdcCmd = req->bRequest;
          cdcLen = req->wLength;
          
          /* Prepare the reception of the buffer over EP0
          Next step: the received data will be managed in usbd_cdc_EP0_TxSent() 
          function. */
          USBD_CtlPrepareRx (pdev,
                             CmdBuff,
                             req->wLength);          
        }
      }
      else /* No Data request */
      {
        /* Transfer the command to the interface layer */
        APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
      }
      
      return USBD_OK;
      
    default:
      USBD_CtlError (pdev, req);
      return USBD_FAIL;
    
      
      
    /* Standard Requests -------------------------------*/
  case USB_REQ_TYPE_STANDARD:
    switch (req->bRequest)
    {
    case USB_REQ_GET_DESCRIPTOR: 
      if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
      {
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
        pbuf = usbd_cdc_Desc;   
#else
        pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
#endif 
        len = MIN(USB_CDC_DESC_SIZ , req->wLength);
      }
      
      USBD_CtlSendData (pdev, 
                        pbuf,
                        len);
      break;
      
    case USB_REQ_GET_INTERFACE :
      USBD_CtlSendData (pdev,
                        (uint8_t *)&usbd_cdc_AltSet,
                        1);
      break;
      
    case USB_REQ_SET_INTERFACE :
      if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
      {
        usbd_cdc_AltSet = (uint8_t)(req->wValue);
      }
      else
      {
        /* Call the error management function (command will be nacked */
        USBD_CtlError (pdev, req);
      }
      break;
    }
  }
  return USBD_OK;
}

/**
  * @brief  usbd_cdc_EP0_RxReady
  *         Data received on control endpoint
  * @param  pdev: device device instance
  * @retval status
  */
static uint8_t  usbd_cdc_EP0_RxReady (void  *pdev)
{ 
  if (cdcCmd != NO_CMD)
  {
    /* Process the data */
    APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
    
    /* Reset the command variable to default value */
    cdcCmd = NO_CMD;
  }
  
  return USBD_OK;
}

/**
  * @brief  usbd_audio_DataIn
  *         Data sent on non-control IN endpoint
  * @param  pdev: device instance
  * @param  epnum: endpoint number
  * @retval status
  */
static uint8_t  usbd_cdc_DataIn (void *pdev, uint8_t epnum)
{
  if(epnum == (CDC_IN_EP&0x7F))
  {
    //DCD_EP_Flush(pdev, CDC_IN_EP);
    USB_StatusDataSended = 1;
  }
  return USBD_OK;
}

/**
  * @brief  usbd_audio_DataOut
  *         Data received on non-control Out endpoint
  * @param  pdev: device instance
  * @param  epnum: endpoint number
  * @retval status
  */
u32 BMP_START_FLAG=0;
u32 BMP_END_FLAG=0;
u32 Demura_START_FLAG=0;
u32 Demura_Pre_FLAG = 0;   //TC1105 demura  parameter data
static uint8_t  usbd_cdc_DataOut (void *pdev, uint8_t epnum)
{      
	u16 i=0;u32 TotalNum=0;
	u16 temp_spi_num=0;
	if(epnum == (CDC_OUT_EP&0x7F))
	{
		USB_ReceivedCount = USBD_GetRxCount(pdev,epnum);
		/* Prapare EP to Receive next Cmd */
		DCD_EP_PrepareRx (pdev,CDC_OUT_EP,(uint8_t *)USB_Rx_Buffer,sizeof(USB_Rx_Buffer)); 
		if((BMP_START_FLAG==2)&&(USB_ReceivedCount>1))  //显示BMP
		{	                 
			if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
			{
				UsbBMPData2FPGAbyFSMC(USB_Rx_Buffer);
			}
			else if(OLED.SigMode == CMD_Mode)  //Command
			{	
				SPI_CS_Select(CS_Master,0);
				SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer,OLED.H_pixel,1,0);
				SPI_CS_Select(CS_Master,1);
			}
			else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
			{    
				SPI_WriteRAM_buffer_part(OLED.SigMode,CS_Master,buffer,OLED.H_pixel,1,Rec_first_line_Flag,DUAL_SPI_MODE);
				if(Rec_first_line_Flag == 1)
				Rec_first_line_Flag = 0;
			} 
                      
		}	
		else if((USB_Rx_Buffer[0]==0X5A)&&(USB_ReceivedCount==1)) //显示BMP结束
		{			
			NUM=0;
			{            
				BMP_START_FLAG=0;//BMP_END_FLAG=0;
				if(OLED.SigMode == Mipi_Mode)
				{
					Load_done_HIGH;
					FSMC_BMP_NUM(Valid_BMP_No);                     //当前画面序号
				}
				STM2PC_ERROR(pdev,CDC_IN_EP,0x0A,0x03,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok 
			}
		}		
		else if((Demura_START_FLAG==1)&&(USB_ReceivedCount>1))  //Demura 数据搬入
		{			
			DemuraData2DDICRam(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
		}
		else if((Demura_Pre_FLAG==1)&&(USB_ReceivedCount>1))  //谱瑞demura配置文件 数据搬入
		{			
			DemuraParamentWrite(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
		}
		else if((Demura_START_FLAG==11)&&(USB_ReceivedCount>1))  //谱瑞demura数据 数据搬入
		{			
			Demura_purui(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
		}
		
		else if((Demura_START_FLAG==2)&&(USB_ReceivedCount>1))  //兼容旧版的新Demura 数据搬入
		{			
			if(DemuraIctype == 0x5e)
			{
				Demura_shenxian(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
			}
			else
				Demura2RAM(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
		}
		else if((Demura_START_FLAG==3)&&(USB_ReceivedCount>1))  //通用自定义数据搬入
		{			
			Demura2RAM_Gen(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,buffer,LP_B7_Data,HS_B7_Data);
		}
//		else if((USB_Rx_Buffer[0]==0X5B)&&(USB_ReceivedCount==1)) //Demura数据搬入结束
//		{			
//			Demura_START_FLAG=0;USB_Rx_Demura=0;
//		}
		else //if(USB_ReceivedCount>1)
		{
			if ( (USB_ReceivedCount<510)&& ( (USB_Rx_Buffer[1]&0xc0) >0) ) //----新指令格式/协议专用
			{//如果此时传过来的不是图片数据，且标志位USB_Rx_Buffer[1]的高两位大于0：此时指令格式为新版
				TotalNum=(USB_Rx_Buffer[2]+((USB_Rx_Buffer[1]&0xc0)>>6)*128);
			}//
			else TotalNum=0;//----新指令格式/协议专用
			if((USB_ReceivedCount==REC_LCDCONF_NUM)&&(USB_Rx_Demura==0)&&(NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))      //接受的数据长度 固定   
			{//接受固定数据长度 
				if(USB_Rx_Buffer[0]==REC_LCDCONF_START||USB_Rx_Buffer[0]==REC_LCDCONF_CONVERT)          //上位机 发送模组Timing参数、ICS307配置参数、通道数  0X0A
				{
					Uart_rx_flag = USB_Rx_Buffer[1];  //功能标志
					crc16_data = crc16(USB_Rx_Buffer,USB_Rx_Buffer[2]+4-2,0xFFFF);
					if(crc16_data == ((USB_Rx_Buffer[USB_Rx_Buffer[2]+4-2]<<8)|(USB_Rx_Buffer[USB_Rx_Buffer[2]+4-1])))
					{
						if(REC_W_LCDCONF_FLAG == Uart_rx_flag)		//上位机 发送 LCDConfig 数据
						{   
							FPGA_ResetProcess();
							Load_done_LOW;
							
							//配置ICS307时钟芯片
							ICS307_Valid_Data = (u32)(USB_Rx_Buffer[16]<<24)|(u32)(USB_Rx_Buffer[15]<<16)|(u32)(USB_Rx_Buffer[14]<<8)|(u32)(USB_Rx_Buffer[13]);
							OLED.DisMode = ((USB_Rx_Buffer[18]&0x0f)<=2) ? 0 : 1;
							OLED.RGBMode = USB_Rx_Buffer[18]&0x0f;
							OLED.H_pixel = (OLED.DisMode == 0) ? (u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]) : 2*((u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]));
							OLED.V_pixel =  (u16)(USB_Rx_Buffer[8]<<8)|(USB_Rx_Buffer[9]);
							OLED.pixel_clk = (float)((((u16)(USB_Rx_Buffer[21]<<8)+USB_Rx_Buffer[20]))/10.0);
							ICS307_ValidClk_Set(ICS307_Valid_Data);
							if((USB_Rx_Buffer[18]&0XF0) < 0x20)
							{
								OLED.SigMode = USB_Rx_Buffer[18]&0XF0;
							}
							else if((USB_Rx_Buffer[18]&0XF0) >= 0x20)
							{
								switch((USB_Rx_Buffer[18]&0XF0))
								{
									case 	0x20:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x00;
									}break;
									case	0x30:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x01;
									}break;
									case	0x40:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x02;
									}break;
									case	0x50:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x03;
									}break;
									case	0x60:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x04;
									}break;
									case	0x70:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x05;
									}break;
								}
							}
		
							if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))
							{
								write_cmd(0x1234);						//将OLED时序数据发送到FPGA
								write_cmd((u16)(USB_Rx_Buffer[4]<<8)|(USB_Rx_Buffer[3]) );	
								write_cmd((u16)(USB_Rx_Buffer[9]<<8)|(USB_Rx_Buffer[8]) );                                
								write_cmd((u16)(USB_Rx_Buffer[6]<<8) ) ;                               
								write_cmd((u16)(USB_Rx_Buffer[11]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[5]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[10]<<8 ) );	
								write_cmd((u16)(USB_Rx_Buffer[7]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[12]<<8) ) ;	                                      
								write_cmd((u16)(USB_Rx_Buffer[18]<<8) + ((OLED.SigMode == Mipi_Mode) ? 0x00 : 0x01 )) ;	
								write_cmd((u16)(USB_Rx_Buffer[17]));	
								write_cmd(0x4321); 
							}                        
								if(OLED.DisMode!= 0)
										CS_Master = CS1_2;
								else
										CS_Master = CS1;
								CS_Slaver = CS2;                               
								SSD28xxCode_count = 0;
								InitCode_count = 0;
								Set_2828_reset(OLED.SigMode);       //复位2828和OLED模组
								STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok                       
						}
						else if(REC_LCDCONF_CONVERT == Uart_rx_flag)		//上位机 发送 LCDConfig 数据
						{
							FPGA_RESET_LOW;			//FPGA复位
							delay_ms(30);
							FPGA_RESET_HIGH;
							delay_ms(100);										
						//配置ICS307时钟芯片
							ICS307_Valid_Data = (u32)(USB_Rx_Buffer[16]<<24)|(u32)(USB_Rx_Buffer[15]<<16)|(u32)(USB_Rx_Buffer[14]<<8)|(u32)(USB_Rx_Buffer[13]);
							OLED.DisMode = ((USB_Rx_Buffer[18]&0x0f)<=2) ? 0 : 1;
							OLED.RGBMode = USB_Rx_Buffer[18]&0x0f;
							OLED.H_pixel = (OLED.DisMode == 0) ? (u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]) : 2*((u16)(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]));
							OLED.V_pixel =  (u16)(USB_Rx_Buffer[8]<<8)|(USB_Rx_Buffer[9]);
							OLED.pixel_clk = (float)((((u16)(USB_Rx_Buffer[21]<<8)+USB_Rx_Buffer[20]))/10.0);
							ICS307_ValidClk_Set(ICS307_Valid_Data);                        
							if((USB_Rx_Buffer[18]&0XF0) < 0x20)
							{
								OLED.SigMode = USB_Rx_Buffer[18]&0XF0;
							}
							else if((USB_Rx_Buffer[18]&0XF0) >= 0x20)
							{
								switch((USB_Rx_Buffer[18]&0XF0))
								{
									case 	0x20:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x00;
									}break;
									case	0x30:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x01;
									}break;
									case	0x40:
									{
										OLED.SigMode = 0x20;
										DUAL_SPI_MODE = 0x02;
									}break;
									case	0x50:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x03;
									}break;
									case	0x60:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x04;
									}break;
									case	0x70:
									{
										OLED.SigMode = 0x30;
										DUAL_SPI_MODE = 0x05;
									}break;
								}
							}
							if(OLED.SigMode == CMD_Mode||OLED.SigMode == Mipi_Mode)
							{
								write_cmd(0x1234);						//将OLED时序数据发送到FPGA
								write_cmd((u16)(USB_Rx_Buffer[4]<<8)|(USB_Rx_Buffer[3]) );	
								write_cmd((u16)(USB_Rx_Buffer[9]<<8)|(USB_Rx_Buffer[8]) );                                
								write_cmd((u16)(USB_Rx_Buffer[6]<<8) ) ;                               
								write_cmd((u16)(USB_Rx_Buffer[11]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[5]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[10]<<8 ) );	
								write_cmd((u16)(USB_Rx_Buffer[7]<<8) ) ;	
								write_cmd((u16)(USB_Rx_Buffer[12]<<8) ) ;	                                      
								write_cmd((u16)(USB_Rx_Buffer[18]<<8) + ((OLED.SigMode == Mipi_Mode) ? 0x00 : 0x01 )) ;	
								write_cmd((u16)(USB_Rx_Buffer[17]));	
								write_cmd(0x4321); 
								CS_Master = CS1_2;	
						
								FSMC_Pure_colour(0x000000);
								Load_done_HIGH;	
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xB7,HS_B7_Data);	
								delay_ms(5);
								FSMC_Pure_colour(0x000000);
						//	Valid_BMP_No--;
						//	if (Valid_BMP_No==255)	Valid_BMP_No=PicShowedNum;
						//	FSMC_BMP_NUM(Valid_BMP_No);                     //当前画面序号												
			 //当前画面序号
							}
							else
							{
								Load_done_LOW;	
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xB7,LP_B7_Data);	
							}
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok   				
						}							
 /*         
						else if(REC_R_LCDCONF_FLAG == Uart_rx_flag)	//上位机 读取 LCDConfig 数据
                        {										
                            i = 0;
                            WriteAddress = Inter_Flash_Addr;
                            FLASH_If_Read(&WriteAddress, buffer1, 0,2048);	//将FLASH的模组Timing数据读取出来，准备发送给FPGA
                            for(i=0;i<16;i++)
                            {
                                    USB_Rx_Buffer[i*4]     = (u8)(buffer1[i]>>24);
                                    USB_Rx_Buffer[(i*4)+1] = (u8)(buffer1[i]>>16);
                                    USB_Rx_Buffer[(i*4)+2] = (u8)(buffer1[i]>>8);
                                    USB_Rx_Buffer[(i*4)+3] = (u8)(buffer1[i]);
                            }									
                            if((USB_Rx_Buffer[0] == 0x47)&&(USB_Rx_Buffer[1] == 0x56)&&(USB_Rx_Buffer[2] == 0x4F)&&(USB_Rx_Buffer[3] == 0x43)&&(USB_Rx_Buffer[4] == 0x6F)&&(USB_Rx_Buffer[5] == 0x6E))
                                STM2PC_LCDConfig(pdev,CDC_IN_EP,Uart_rx_flag,USB_Rx_Buffer,Uart_Error_None);       //返回 读LCD_Config状态 ：ok；将LCD_Config数据返回
                            else
                                STM2PC_LCDConfig(pdev,CDC_IN_EP,Uart_rx_flag,USB_Rx_Buffer,Uart_Error_IntFlash);	//返回 flash内部没有配置文件 ：error									
                    
                        }
	*/											
						else if((REC_W_PATTERN_FLAG == Uart_rx_flag)||(REC_W_RARTIAL_PATTERN_FLAG == Uart_rx_flag))	//上位机 发送 画面颜色 数据
						{	
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);
							if(OLED.SigMode == Mipi_Mode)
							{       
								#if DSI_Set_Window_EN == 1
									SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
								#endif                                
								if(REC_W_PATTERN_FLAG == Uart_rx_flag)
								{
									FSMC_Pure_colour((u32)(USB_Rx_Buffer[3]<<16)|((u32)(USB_Rx_Buffer[4]<<8)|USB_Rx_Buffer[5]));
								}
								else //IF REC_W_RARTIAL_PATTERN_FLAG
								{
									FSMC_Pure_colour_Partial_Display(USB_Rx_Buffer[9]<<8|USB_Rx_Buffer[10],USB_Rx_Buffer[11]<<8|USB_Rx_Buffer[12],USB_Rx_Buffer[13]<<8|USB_Rx_Buffer[14],USB_Rx_Buffer[15]<<8|USB_Rx_Buffer[16],(u32)(USB_Rx_Buffer[6]<<16)|((u32)(USB_Rx_Buffer[7]<<8)|USB_Rx_Buffer[8]),(u32)(USB_Rx_Buffer[3]<<16)|((u32)(USB_Rx_Buffer[4]<<8)|USB_Rx_Buffer[5]));
								}
								Load_done_HIGH;
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xB7,HS_B7_Data);
								PatternR = USB_Rx_Buffer[3];
								PatternG = USB_Rx_Buffer[4];
								PatternB = USB_Rx_Buffer[5]; 
							}
							else if(OLED.SigMode == CMD_Mode)           //Command 模式
							{
								#if DSI_Set_Window_EN == 1                    
									SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
								#endif
									SSD2828_W_RAM_Pic(OLED.pixel_clk,OLED.SigMode,CS_Master,OLED.H_pixel,OLED.V_pixel,USB_Rx_Buffer[3],USB_Rx_Buffer[4],USB_Rx_Buffer[5]);                        
							}
							else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
							{
								#if SPI_Set_Window_EN == 1                                 
									SPI_Set_Window(OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
								#endif
									SPI3_WriteRAM(OLED.SigMode,CS_Master,OLED.H_pixel,OLED.V_pixel,USB_Rx_Buffer[3],USB_Rx_Buffer[4],USB_Rx_Buffer[5],DUAL_SPI_MODE);
							}

						}
						else if(REC_R_PATTERN_FLAG == Uart_rx_flag)	//上位机 读取 画面颜色 数据
						{		
							STM2PC_Pattern(pdev,CDC_IN_EP,USB_Rx_Buffer[0],PatternR,PatternG,PatternB,Uart_Error_None);
						}
						else if(Uart_rx_flag == PrevPic)	//显示上一幅图片
						{		
							Valid_BMP_No--;
							if (Valid_BMP_No==255)	Valid_BMP_No=PicShowedNum;
							FSMC_BMP_NUM(Valid_BMP_No);                     //当前画面序号
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,Valid_BMP_No); 
						}
						else if(Uart_rx_flag == NextPic)	//显示下一幅图片
						{		
							Valid_BMP_No++;if (Valid_BMP_No>PicShowedNum)	Valid_BMP_No=0;
							FSMC_BMP_NUM(Valid_BMP_No); 
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,Valid_BMP_No); 
						//*pdev,uint8_t  ep_addr,   u8 State,        u8 CMD, u8 ERROR_CODE,u8 Other_data)
						}
						else if(REC_R_SW_VERSION_FLAG == Uart_rx_flag)	//上位机 读取 SW 版本号
						{
							if((USB_Rx_Buffer[3] == FW_Version)&&(USB_Rx_Buffer[4] == FW_SubVersion))
							{
								STM2PC_SW_Version(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,FW_Version, FW_SubVersion,Device_ID);
							}
							else 
							{
								STM2PC_SW_Version(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_Oth,FW_Version, FW_SubVersion,Device_ID);
								if((USB_Rx_Buffer[3] == 0)&&(USB_Rx_Buffer[4] == 0))
								{
									while(1)
									{
										delay_ms(500);
										LED_LOW;
										LED2_HIGH;
										delay_ms(500);
										LED2_LOW;
										LED_HIGH;
									}
								}
							}
						}
						else if(REC_W_DeviceID_FLAG == Uart_rx_flag)	//上位机 写入ID
						{
							Device_ID_Buf[0] = (USB_Rx_Buffer[3]!=0) ? (u32)(USB_Rx_Buffer[3]-0x30)*10+ (u32)(USB_Rx_Buffer[4]-0x30) : (u32)(USB_Rx_Buffer[4]-0x30);
							Device_ID = Device_ID_Buf[0];
							FLASH_Unlock();		//芯片内部FLASH每次操作都需要解锁
							if(Device_Addr == Device_Flash_Addr + 0x10000)
							{
								Device_Addr = Device_Flash_Addr;
								FLASH_EraseSector(Device_Flash_Sect, VoltageRange_3);
							}
								FLASH_If_Write(&Device_Addr, Device_ID_Buf, 1);
								FLASH_Lock();		//FLASH操作结束，锁上 
								STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);
							}
						else if(REC_W_DISP_WINDOW_CONF_FLAG == Uart_rx_flag) //上位机 发送 开窗显示数据
						{
							OLED_X0=(USB_Rx_Buffer[3]<<8)|(USB_Rx_Buffer[4]);
							OLED_X1=(USB_Rx_Buffer[5]<<8)|(USB_Rx_Buffer[6]);
							OLED_Y0=(USB_Rx_Buffer[7]<<8)|(USB_Rx_Buffer[8]);
							OLED_Y1=(USB_Rx_Buffer[9]<<8)|(USB_Rx_Buffer[10]);
							OLED_X_VALUE=OLED_X1-OLED_X0;
							OLED_Y_VALUE=OLED_Y1-OLED_Y0;
						
							OLED.H_pixel = (OLED.DisMode == 0) ? OLED_X_VALUE : 2*OLED_X_VALUE;
							OLED.V_pixel =  OLED_Y_VALUE;
							SSD2828_Set_Window(OLED.SigMode ,CS_Master,OLED_X0,OLED_X1,OLED_Y0,OLED_Y1);
													
							STM2PC_ERROR(pdev,CDC_IN_EP,USB_Rx_Buffer[0],Uart_rx_flag,Uart_Error_None,0);           //返回 写LCD_Config状态  ：ok   														
						}
					}
				}                                                                      
			}
			else if ((USB_Rx_Buffer[0]==BMP_FLAG)&&(USB_Rx_Buffer[1]==0x5a)&&(USB_Rx_Buffer[2]==0xa5)&&(USB_Rx_Buffer[3]==0x9d)&&(USB_Rx_Buffer[4]==0xf0))
			{
				BMP_START_FLAG=1;
				if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
				{
					#if DSI_Set_Window_EN == 1                    
						SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
					#endif                   
					if(Valid_BMP_No==25)
					{					
						Valid_BMP_No=0;
					}
					else
					{
						Valid_BMP_No++;
						if(PicShowedNum<25) PicShowedNum++;
					}
					write_cmd(0x3456); //将OLED时序数据发送到FPGA
					delay_us(4);
					write_cmd((u16)(((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5)>>16));				//	0:H_PIXEL	1:H_B	2:H_F	3:H_S	4:高8(单双6,8)
					delay_us(4);
					write_cmd((u16)((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5));						//	0:V_PIXEL	1:V_B	2:V_F	3:V_S	4:无效
					delay_us(4);
					write_cmd(0x6543);
					delay_us(4);
				}
				else if(OLED.SigMode == CMD_Mode)  //Command
				{             
					#if DSI_Set_Window_EN == 1                    
							SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
					#endif
					SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBC,(u16) (OLED.H_pixel*OLED.V_pixel*3)); 
					SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBD,(u16)((OLED.H_pixel*OLED.V_pixel*3)>>16)); 
					if(OLED.H_pixel*3<=4095)
					{
							SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3)); 
					}			
					else
					{
							SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16)(OLED.H_pixel*3/2)); 
					}
					SSD2828_W_Cmd(OLED.SigMode,CS_Master,0xBF);
					SSD2828_W_Cmd(OLED.SigMode,CS_Master,0X2C);
				}
				else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
				{
					#if SPI_Set_Window_EN == 1
							SPI_Set_Window  (OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
					#endif
				//	SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x01);
				//	SPI_Write_code  (OLED.SigMode,CS_Master ,0x04,0x80);
				//	SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x00);
				//	SPI_Write_code  (OLED.SigMode,CS_Master ,0xC4,0x31);        // SPI3-SP3T 2Wire
				}
			}
			else if ((USB_Rx_Buffer[0]==BMP_FLAG)&&(USB_Rx_Buffer[1]==0xa5)&&(USB_Rx_Buffer[2]==0x5a)&&(USB_Rx_Buffer[3]==0x9d)&&(USB_Rx_Buffer[4]==0xf0))
			{
				BMP_START_FLAG=2; //新格式传输，速度更快
				if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
				{
					#if DSI_Set_Window_EN == 1                    
						SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
					#endif                   
					if(Valid_BMP_No==25)
					{					
						Valid_BMP_No=0;
					}
					else
					{
						Valid_BMP_No++;
						if(PicShowedNum<25) PicShowedNum++;
					}
					write_cmd(0x3456); //将OLED时序数据发送到FPGA
					delay_us(4);
					write_cmd((u16)(((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5)>>16));				//	0:H_PIXEL	1:H_B	2:H_F	3:H_S	4:高8(单双6,8)
					delay_us(4);
					write_cmd((u16)((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5));						//	0:V_PIXEL	1:V_B	2:V_F	3:V_S	4:无效
					delay_us(4);
					write_cmd(0x6543);
					delay_us(4);
				}
				else if(OLED.SigMode == CMD_Mode)  //Command
				{             
					#if DSI_Set_Window_EN == 1                    
						SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
					#endif
					SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBC,(u16) (OLED.H_pixel*OLED.V_pixel*3)); 
					SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBD,(u16)((OLED.H_pixel*OLED.V_pixel*3)>>16)); 
					if(OLED.H_pixel*3<=4095)
					{
						SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3)); 
					}			
					else
					{
						SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16)(OLED.H_pixel*3/2)); 
					}
						SSD2828_W_Cmd(OLED.SigMode,CS_Master,0xBF);
						SSD2828_W_Cmd(OLED.SigMode,CS_Master,0X2C);
				}
				else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
				{
					#if SPI_Set_Window_EN == 1
					SPI_Set_Window  (OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
					#endif
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x01);
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0x04,0x80);
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x00);
                   //     SPI_Write_code  (OLED.SigMode,CS_Master ,0xC4,0x31);        // SPI3-SP3T 2Wire
											
											//以上四句SPI_Write_code也可以用一下两句代替（DSPI指令，RM69091 IC MIPI切SPI指令）											
											// SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x00);
											//	SPI_Write_code  (OLED.SigMode,CS_Master ,0xC4,0xB1);  
				}
			}
			// Set Demura_START_FLAG
			else if ((USB_ReceivedCount==9)&&(USB_Rx_Buffer[0]==BMP_FLAG)&&(USB_Rx_Buffer[1]==0x5b)&&(USB_Rx_Buffer[2]==0xb5)&&(USB_Rx_Buffer[3]==0xd9)&&(USB_Rx_Buffer[4]==0x9d))
			{
				Demura_START_FLAG=1; //新格式传输，保持Demura部分的独立性，HFZ部分窗体使用
				USB_Rx_Demura=0;
				USB_Rx_Demura_Total_Num=(USB_Rx_Buffer[5]<<24)+(USB_Rx_Buffer[6]<<16)+(USB_Rx_Buffer[7]<<8)+USB_Rx_Buffer[8];
			}
			//TC1105芯片处理demura配置文件数据
			else if ((USB_ReceivedCount==6)&&(USB_Rx_Buffer[0]==0xbd)&&(USB_Rx_Buffer[1]==0xcf)&&(USB_Rx_Buffer[2]==0xdf)&&(USB_Rx_Buffer[3]==0xef)&&(USB_Rx_Buffer[4]==0xff))
			{
				  USB_DemuraParament_Num = USB_Rx_Buffer[5];
				  Demura_Pre_FLAG = 1;         
			}
			//TC1105芯片处理demuradata文件数据
			else if ((USB_ReceivedCount==9)&&(USB_Rx_Buffer[0]==0xbd)&&(USB_Rx_Buffer[1]==0x5b)&&(USB_Rx_Buffer[2]==0xb5)&&(USB_Rx_Buffer[3]==0xdd)&&(USB_Rx_Buffer[4]==0xbb))
			{
				  USB_Rx_Demura_Total_Num=(USB_Rx_Buffer[5]<<24)+(USB_Rx_Buffer[6]<<16)+(USB_Rx_Buffer[7]<<8)+USB_Rx_Buffer[8];
				  Demura_START_FLAG = 11;             
			}
			
			else if ((USB_ReceivedCount==11)&&(USB_Rx_Buffer[2]==BMP_FLAG)&&(USB_Rx_Buffer[3]==0xcf)&&(USB_Rx_Buffer[4]==0xfc)&&(USB_Rx_Buffer[5]==0xac)&&(USB_Rx_Buffer[6]==0xca))
			{
				Demura_START_FLAG=2; //兼容旧版用的新格式传输，保持Demura部分的独立性/供前期旧版本兼容用
				USB_Rx_Demura=0;
				DemuraIctype=USB_Rx_Buffer[0]; //获取IC型号		
				Demura_OLEDModule_flag=USB_Rx_Buffer[1]	; //获取产品型号			
				USB_Rx_Demura_Total_Num=(USB_Rx_Buffer[7]<<24)+(USB_Rx_Buffer[8]<<16)+(USB_Rx_Buffer[9]<<8)+USB_Rx_Buffer[10];
			}
			else if ((USB_ReceivedCount==12)&&(USB_Rx_Buffer[0]==GEN_FLAG)&&(USB_Rx_Buffer[4]==0xcf)&&(USB_Rx_Buffer[5]==0xfc)&&(USB_Rx_Buffer[6]==0xac)&&(USB_Rx_Buffer[7]==0xca))
			{
				Demura_START_FLAG=3; 
				USB_Rx_Demura=0;
				DemuraIctype=USB_Rx_Buffer[1];
				DemuraSize_H8=USB_Rx_Buffer[2]; //每笔数据分频量高8位		
				DemuraSize_L8=USB_Rx_Buffer[3];//每笔数据分频量低8位			
				USB_Rx_Demura_Total_Num=(USB_Rx_Buffer[8]<<24)+(USB_Rx_Buffer[9]<<16)+(USB_Rx_Buffer[10]<<8)+USB_Rx_Buffer[11];
			}
			else if((((USB_Rx_Buffer[0]==REC_SSD_CODE_START)&&(USB_Rx_Demura==0)&&(NUM==0)&&(BMP_START_FLAG==0))||(Receive_Code_flag == 1))&&(Receive_BIN_Flag == 0))      //接受的 数据 长度非固定
			{
				if(Receive_Code_flag == 0)
				{
					Receive_Code_flag = 1;
					Uart_rx_flag=USB_Rx_Buffer[1]&0x0f;
				}
				for(i=0;i<USB_ReceivedCount;i++)
				{	
					buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i];
				}
				VCP_Receive_True_num+=USB_ReceivedCount;
				if(VCP_Receive_True_num==(buffer[1]>>4)*256+buffer[2]+5)
				{
					Receive_Code_flag = 0;
					if((REC_W_SSD_ONE_FLAG == Uart_rx_flag)||(REC_W_SSD_FLAG == Uart_rx_flag))		//上位机  发送 SSD2828 命令
					{
						SSD28xxCode_count = 0;
						STM2PC_ERROR(pdev,CDC_IN_EP,buffer[0],Uart_rx_flag,Uart_Error_None,0);
						if(REC_W_SSD_ONE_FLAG == Uart_rx_flag)
						{
							if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
							{      
								SSD2828_W_Reg(OLED.SigMode,CS_Master,buffer[3],(u16)(buffer[4]<<8)|buffer[5]);
							}
							else if(OLED.SigMode == CMD_Mode)//Command
							{
								SSD2828_W_Reg(OLED.SigMode,CS_Master,buffer[3],(u16)(buffer[4]<<8)|buffer[5]);                                 
							}
							if(buffer[3] == 0xB7)
							{
								if(((u16)(buffer[4]<<8)|buffer[5])&0x0001)
									HS_B7_Data = (u16)(buffer[4]<<8)|buffer[5];
								else
									LP_B7_Data = (u16)(buffer[4]<<8)|buffer[5];
							}                           
						}
						else
						{
							if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))
							{
								for (i = 0; i < 512; i++)		//将2828的配置数据 转换成字
								{
									if (buffer[i * 3 +3] == 0xff)
									{
													break;                    
									}
									//    0x H H H H  :   31:24->00(没作用)   23:16->寄存器地址    15:0->寄存器值(高位在前)
									SSD28xx_Code[SSD28xxCode_count] = ((uint32_t)buffer[i * 3 +3]<<16) + ((uint32_t)buffer[i * 3 + 1+3]<<8) + ((uint32_t)buffer[i * 3 + 2+3]);
									SSD28xxCode_count ++;	
									if(buffer[i * 3 +3] == 0xB7)
									{
										if(((u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5])&0x0001)
										{
											HS_B7_Data = (u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5];
										}
										else
											LP_B7_Data = (u16)(buffer[i * 3 +4]<<8)|buffer[i * 3 +5];                                         
									}                                        
								}
								SSD2828_initial_on(OLED.SigMode,CS_Master); //download 2828 cfg
							}                                                            
						} 
					}
					else if((REC_W_CODE_ONE_FLAG == Uart_rx_flag)||(REC_W_CODE_FLAG == Uart_rx_flag))		//上位机  发送 DriverIC code
					{	
						InitCode_count = 0;
						STM2PC_ERROR(pdev,CDC_IN_EP,buffer[0],Uart_rx_flag,Uart_Error_None,0);
						if(REC_W_CODE_ONE_FLAG == Uart_rx_flag)
						{
							if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))  //RGB+SPI= MIPI
							{									
								SSD2828_W_Array(OLED.SigMode,CS_Master,buffer,2);
							}
							else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
							{
								temp_spi_num = buffer[2];
								for(i=0;i<temp_spi_num+1;i++)
								{   buffer[i] = buffer[i+2];    }
								if(buffer[0] > 1)
								{
									SPI_Write_u8_Array(OLED.SigMode,CS_Master,buffer);
								}
								else if(buffer[0] == 1)
								{
									SPI_Write_u8_Cmd(OLED.SigMode,CS_Master,buffer[1]);
									if(buffer[1] == 0x11){		delay_ms(120);	}
									delay_ms(1);
								}  
							}
						}
						else
						{
							for (i = 3; i < 4096; i += (Code_length+1))
							{
								Code_length = buffer[i];	//每一句初始化代码的 数据长度

								if (Code_length == 0xff)	//判断长度有255说明 ，到初始化代码的最后
								{
									break;
								}
								Timing_and_InitCode[0] =	Code_length;	//数组中的[0]：这一句初始化代码的数据长度									
								for (j = 1; j < Code_length+1; j++)	//递增将 初始化代码写入到数组
								{											
									Timing_and_InitCode[j] = ((uint32_t)buffer[i+j]);
								}									
								for(j=0;j<Timing_and_InitCode[0]+1;j++)			//整合一行初始化全部内容									
									InitCode_valid[InitCode_count][j] = (u8)Timing_and_InitCode[j];
								
								InitCode_count ++;	//即将写下一个数组(下一句初始化代码)
							}
							if((OLED.SigMode == Mipi_Mode)||(OLED.SigMode == CMD_Mode))  //RGB+SPI= MIPI
							{									
									//SSD2828_signal_on(OLED.SigMode,CS_Master);
								Driver_ic_initial_on(OLED.SigMode,CS_Master);
							}
							else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
							{
								SPI_signal_on(OLED.SigMode,CS_Master);
							}
						}                      
					}
					else if(REC_R_CODE_FLAG == Uart_rx_flag)		//上位机  读取 DriverIC code
					{
					
					}    
					VCP_Receive_True_num = 0;
				}                
			}
			else if(  ((USB_ReceivedCount==USB_Rx_Buffer[2]+5)|(USB_ReceivedCount==TotalNum+6))   &&(USB_Rx_Demura==0)&&(NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))   //数据长度 固定
			{	//--配置DDIC,处理初始化、OTP、Gamma Demura基本操作 等功能---	
				Uart_rx_flag=USB_Rx_Buffer[1]&0x0f;	//？							
				if (TotalNum>0)  //临时判断传过来的新旧指令表，只有新指令表时，TotalNum才大于零
				{	
					crc16_data1 = crc16(USB_Rx_Buffer,TotalNum+4,0xFFFF);
					if (crc16_data1 == ((USB_Rx_Buffer[TotalNum+4]<<8)|(USB_Rx_Buffer[TotalNum+5])))
						crc16_data1=1; //crc16_data1默认为0，crc16_data1=1意味着通过新协议传过来的数据是正确的
					else 
					{
						crc16_data1=0;	
					}
				}//其实如果此时传输中出现错误，则....TODO
				crc16_data = crc16(USB_Rx_Buffer,USB_Rx_Buffer[2]+3,0xFFFF);
				if(crc16_data1|(crc16_data == ((USB_Rx_Buffer[USB_Rx_Buffer[2]+3]<<8)|(USB_Rx_Buffer[USB_Rx_Buffer[2]+4]))))
				{
					switch (USB_Rx_Buffer[0])
					{
						case Rec_R_Config_Start:
						{
							if(Rec_R_Config_flag == Uart_rx_flag)		//上位机  读取  配置文件 命令
							{
								WriteAddress = Inter_Flash_Addr;
								SendTo_PC_cfgFile=1;
							}
							break;
						}
						//else if(USB_Rx_Buffer[0]==REC_UPDATABIN_Start)      //接受的 数据 长度非固定      0X55
						case REC_UPDATABIN_Start:
						{
							Receive_BIN_Flag1 = 1;
							Receive_BIN_Length = (USB_Rx_Buffer[3]<<24)+(USB_Rx_Buffer[4]<<16)+(USB_Rx_Buffer[5]<<8)+USB_Rx_Buffer[6];
							USB_Rx_Buffer[4] = Uart_Error_None;
							STM2PC_RM671xx(pdev,CDC_IN_EP,USB_Rx_Buffer,USB_Rx_Buffer[2]+3);           //返回 写寄存器状态  ：ok 
							break;  
						}
						case HX83200:
						{
							ProcessForIc2B(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
						}	break; 												
						case NT37710:
						{
							ProcessForIc2A(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case ICN9608:
						{
							ProcessForIc2D(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case CH13721:
						{
							ProcessForIc4A(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	  
						}	break; 
						case FT2711:
						{
							ProcessForIc4B(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	 
						}	break; 
						case GenWR://万能读写
						{
							ProcessForIc99(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 						
						
						case UD61720:
						{
							ProcessForIc4C(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	  
						}	break; 															
						case RM67120:
						{
							ProcessForIc08(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	                                   
						}	break; 
						case RM67195:
						case RM67295:
						case RM67198:
						case RM67298:										
						{
							ProcessForIc2E(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	             
						}	break;	
						case RM67160:
						case RM67162:
						{
							ProcessForIc1E(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case RM6D010:
						{
							ProcessForIc3D(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case RM69300:
						{
							ProcessForIc2C(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	                   
						}	break; 
						case RM69350:
						{
							ProcessForIc3C(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case R66455:
						{	
							ProcessForIc30(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);											
						}	break; 
						case TC1100:
						{	
							ProcessForIc31(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						//---------------------------------------------------------
						case RM69330:
						{
							ProcessForIc32(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);//ADD BY PCS
							break;
						}
						
						case HX83201A:
						{	
							ProcessForIc51(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							//break;												
						}	break; 
						case VTDR6100:
						{	
							ProcessForIc4D(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							//break;												
						}	break; 
						case RM69310:
						{
							ProcessForIc52(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							//break;
						}
								break;
						case FT2201:
						{
							ProcessForIc53(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
							break;
						}
						//-----------------------------------------------------------
						case DE_MURA: //BYTE[0] 0x2F
						{
							switch(USB_Rx_Buffer[3]) //USB_Rx_Buffer[7] = IC型号，USB_Rx_Buffer[3]用来区分相同IC下的不同产品型号
							{
										//---------------------------------Demura Start---------------------------------------------------------						
								case 0x00: //GM820
								{
									ProcessForDmuR00(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 					
								case 0x01: //GM825
								{
									ProcessForDmuR01(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 	
								case 0x02: //GM830
								{
									ProcessForDmuR02(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 	
								case 0x03: //GM870
								{
									ProcessForDmuR03(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 							
								case 0x04: //RM69297&298&299
								{
									ProcessForDmuR04(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 		
								case 0x05: //GM760
								{
									ProcessForDmuR05(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 		
								case 0x06: //GM620
								{
									ProcessForDmuR06(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 		
								case 0x07: //GM820_NT37700C
								{
									ProcessForDmuR07(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 
								case 0x08: //GM870_VT5100
								{
									ProcessForDmuR08(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;									
								case 0x09: //GM8A0_RM692C9
								case 0x11: //Send_buf[3] = 0x11:692Ax-KPQ/641  ;0x13:692Cx---M2
								case 0x12: //6.088
								case 0x13: //0x13:692Cx---M2
								{
									ProcessForDmuR09(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;		
								case 0x0A: //
								{
									ProcessForDmuR0A(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x0B: //GM8A0_RM69200
								{
									ProcessForDmuR0B(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;			
								case 0x0C: //GT666_RM692A9
								{
									ProcessForDmuR0C(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x0D: //F4_RM692C4
								{
									ProcessForDmuR0D(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break; 
								case 0x0E: //R66451_ALPHA
								{
									ProcessForDmuR0E(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x0F: //R66451_GM862
								{
									ProcessForDmuR0F(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;
								case 0x10:  
								{
									 ProcessForDmuR10(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								}	break;
								case 0x14:  //R69351_GM920
								{
									ProcessForDmuR14(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;		
								case 0x15:  //R692CX_GM828
								{
									ProcessForDmuR15(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x16:  //VTDR6110C_GM8A0
								{
									ProcessForDmuR16(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x17:  //VTDR6110_GM750(601)
								{
									ProcessForDmuR17(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x18:  //R692CX_GM010  //3.92项目
								{
									 ProcessForDmuR18(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;	
								case 0x1F:  //ILI7835_621
								{
									ProcessForDmuR1F(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;
								case 0x20:  //TC1105
								{
									ProcessForDmuR20(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
								}	break;
								case 0x59: //SK622_RM69350
								{
									ProcessForDmuR59(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);		
								}break;
								case 0x60: //SK VTDR7210  
								{
									ProcessForDmuR60(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								}break;
								
								case 0x61: //NT37001_FM010
								{
									ProcessForDmuR61(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
								}break;
								
								//ID请安顺序申请，不用跳阶				
                                    
							}
							//ProcessForIc2F(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case RM692A9:
						{
							ProcessForIc3E(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						
						case NT37700C:
						{
							ProcessForIc4E(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);														
						}	break; 
						
						case RM692C4:   //#define RM692C4				0x3F
						{
							ProcessForIc3F(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case RM692C9:	//#define RM692C9				0x4F  
						{
							ProcessForIc4F(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break;
					    
						case 0x41:    //从这里开始添加新
						{
							ProcessForIc41(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);													
						}	break; 
						case 0x42:   
						{
							ProcessForIc42(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						case ILI7835:   
						{
							ProcessForIc56(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						case ICNA3310:   
						{
							ProcessForIc57(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break;
						case RM69091:   
						{
							ProcessForIc58(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						case RM69350_SK622:   
						{
							ProcessForIc59(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
                        
						case VTDR7120:   //SK 622 VTDR7120
						{
							ProcessForIc60(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);												
						}	break; 
						case RM690A0_GW910:
						{
							ProcessForIc61(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case TC1105:
						{
							ProcessForIc62(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case ILI8688:
						{
							ProcessForIc63(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break; 
						case RM69380 :
						{
							
					  	ProcessForIc64(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break;
						case SD5202:
						{	
							ProcessForIc65(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break;	
						case NT37701:
						{	
							ProcessForIc66(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break;
						case RM69310_GW010:
						{
							ProcessForIc67(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
							break;
						}
						case CMD_CODE://HY.Wang
						{
							ProcessForIcA0(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);	
						}	break;
						case GenWRHFZ:	//#define GenWRHFZ            0x9F
						{
							switch (USB_Rx_Buffer[1]&0x80)
							{            
								case 0:                                      //写寄存器
									HFZGenerate_Write_Function(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								case 0x80:                                      //读寄存器
									//HFZGenerate_Read_Function(pdev,CDC_IN_EP,OLED.SigMode ,CS_Master,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);break;	
								default:	break;	
							}
						}	break; 				
						default:	break;
						
					}
				}                 
			}
			else
			{      //BMP 显示               
				if((NUM==0)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag1 == 0))
				{
					NUM = 1; 
					if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
					{
						#if DSI_Set_Window_EN == 1                    
							SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
						#endif                   
//                        if(Valid_BMP_No==0)
//                        {
//                            Valid_BMP_No=1;
//                        }
//                        else
//                        {
//                            Valid_BMP_No=0;
//                        }
						write_cmd(0x3456); //将OLED时序数据发送到FPGA
						delay_us(40);
						write_cmd((u16)(((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5)>>16));				//	0:H_PIXEL	1:H_B	2:H_F	3:H_S	4:高8(单双6,8)
						delay_us(40);
						write_cmd((u16)((Valid_BMP_No*OLED.V_pixel*OLED.H_pixel)*8/5));						//	0:V_PIXEL	1:V_B	2:V_F	3:V_S	4:无效
						delay_us(40);
						write_cmd(0x6543);
						delay_us(40);
					}
					else if(OLED.SigMode == CMD_Mode)  //Command
					{             
						#if DSI_Set_Window_EN == 1                    
							SSD2828_Set_Window(OLED.SigMode,CS_Master,(OLED.H_pixel==390) ? 4 : 0,(OLED.H_pixel==390) ? OLED.H_pixel+4 : OLED.H_pixel,0,OLED.V_pixel);
						#endif
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBC,(u16) (OLED.H_pixel*OLED.V_pixel*3)); 
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBD,(u16)((OLED.H_pixel*OLED.V_pixel*3)>>16)); 
						if(OLED.H_pixel*3<=4095)
						{
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16) (OLED.H_pixel*3)); 
						}			
						else
						{
								SSD2828_W_Reg(OLED.SigMode,CS_Master,0xBE,(u16)(OLED.H_pixel*3/2)); 
						}
						SSD2828_W_Cmd(OLED.SigMode,CS_Master,0xBF);
						SSD2828_W_Cmd(OLED.SigMode,CS_Master,0X2C);
					}
					else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
					{
						#if SPI_Set_Window_EN == 1
							SPI_Set_Window  (OLED.SigMode,CS_Master,0, OLED.H_pixel-1,0, OLED.V_pixel-1);
						#endif
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x01);
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0x04,0x80);
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0xFE,0x00);
                  //      SPI_Write_code  (OLED.SigMode,CS_Master ,0xC4,0x31);        // SPI3-SP3T 2Wire
					}    
				}
				if((NUM==1)&&(Receive_BIN_Flag == 0)&&(Receive_BIN_Flag == 0))
				{
					for(i=0;i<USB_ReceivedCount;i++)
						buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i];     
						VCP_Receive_True_num+=USB_ReceivedCount;
					if(VCP_Receive_True_num == OLED.H_pixel*3)
					{     
						if(OLED.SigMode == Mipi_Mode)  //RGB+SPI= MIPI
						{
							SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer,OLED.H_pixel,1,OLED.DisMode);
						}
						else if(OLED.SigMode == CMD_Mode)  //Command
						{	
							SPI_CS_Select(CS_Master,0);
							SSD2828_W_RAM_buffer_8bits_part(OLED.pixel_clk,OLED.SigMode,buffer,OLED.H_pixel,1,0);
							SPI_CS_Select(CS_Master,1);
						}
						else if((OLED.SigMode == SPI3_Mode)||(OLED.SigMode == SPI4_Mode))          //3线8bit SPI 模式   //4线8bit SPI 模式
						{    
							SPI_WriteRAM_buffer_part(OLED.SigMode,CS_Master,buffer,OLED.H_pixel,1,Rec_first_line_Flag,DUAL_SPI_MODE);
							if(Rec_first_line_Flag == 1)
								Rec_first_line_Flag = 0;
						} 
						VCP_Receive_True_num=0;
					}	
				}
			}
		} 			      
	}
  return USBD_OK;
}

/**
  * @brief  usbd_audio_SOF
  *         Start Of Frame event management
  * @param  pdev: instance
  * @param  epnum: endpoint number
  * @retval status
  */
static uint8_t  usbd_cdc_SOF (void *pdev)
{      
  static uint32_t FrameCount = 0;
  
  if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
  {
    /* Reset the frame counter */
    FrameCount = 0;
    
    /* Check the data to be sent through IN pipe */
    Handle_USBAsynchXfer(pdev);
  }
  
  return USBD_OK;
}

/**
  * @brief  Handle_USBAsynchXfer
  *         Send data to USB
  * @param  pdev: instance
  * @retval None
  */
static void Handle_USBAsynchXfer (void *pdev)
{
  uint16_t USB_Tx_ptr;
  uint16_t USB_Tx_length;
  
  if(USB_Tx_State != 1)
  {
      //当APP_Rx_ptr_out 达到 APP_RX_DATA_SIZE 时，将其置0，
      //也就是在循环缓冲区中绕了一圈回到缓冲区起始地址。
    if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
    {
      APP_Rx_ptr_out = 0;
    }
     //当 APP_Rx_prt_out 赶上 APP_Rx_ptr_in 时，证明 Buffer 里边的数据已经发送完毕，返回   
    if(APP_Rx_ptr_out == APP_Rx_ptr_in)     //Buffer 里边的数据已经发送完毕
    {
      USB_Tx_State = 0; 
      return;
    }
    
    if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
    { 
      APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
    
    }
    else 
    {
      APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
     
    }
#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
     APP_Rx_length &= ~0x03;
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
    
    if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
    {
      USB_Tx_ptr = APP_Rx_ptr_out;
      USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
      
      APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;	
      APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
    }
    else
    {
      USB_Tx_ptr = APP_Rx_ptr_out;
      USB_Tx_length = APP_Rx_length;
      
      APP_Rx_ptr_out += APP_Rx_length;
      APP_Rx_length = 0;
    }
    USB_Tx_State = 1; 

    DCD_EP_Tx (pdev,
               CDC_IN_EP,
               (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
               USB_Tx_length);
  }  
  
}

/**
  * @brief  USBD_cdc_GetCfgDesc 
  *         Return configuration descriptor
  * @param  speed : current device speed
  * @param  length : pointer data length
  * @retval pointer to descriptor buffer
  */
static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
{
  *length = sizeof (usbd_cdc_CfgDesc);
  return usbd_cdc_CfgDesc;
}

/**
  * @brief  USBD_cdc_GetCfgDesc 
  *         Return configuration descriptor
  * @param  speed : current device speed
  * @param  length : pointer data length
  * @retval pointer to descriptor buffer
  */
#ifdef USE_USB_OTG_HS 
static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
{
  *length = sizeof (usbd_cdc_OtherCfgDesc);
  return usbd_cdc_OtherCfgDesc;
}
#endif
/**
  * @}
  */ 

/**
  * @}
  */ 

/**
  * @}
  */ 

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
